package com.safframework.androidserver.service

import android.app.Service
import android.content.Intent
import android.os.IBinder
import com.safframework.androidserver.log.LogProxyImpl
import com.safframework.server.converter.gson.GsonConverter
import com.safframework.server.converter.gson.GsonUtils
import com.safframework.server.core.Server
import com.safframework.server.core.ServerBuilder
import com.safframework.server.core.enums.ServerType
import com.safframework.server.core.handler.socket.WebSocketListener
import com.safframework.server.core.log.LogManager
import io.netty.buffer.ByteBuf
import io.netty.channel.Channel
import io.netty.handler.codec.http.HttpHeaders
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame
import java.net.InetSocketAddress

/**
 *
 * @FileName:
 *          com.safframework.androidserver.service.SocketService
 * @author: Tony Shen
 * @date: 2020-03-27 17:01
 * @version: V1.0 <描述当前版本功能>
 */
class SocketService : Service() {

    private lateinit var tcpServer: Server

    override fun onCreate() {
        super.onCreate()
        startServer()
    }

    // 启动 Socket 服务端
    private fun startServer() {

        tcpServer = ServerBuilder {
            port {
                8888
            }
            converter {
                GsonConverter()
            }
            logProxy {
                LogProxyImpl
            }
        }.build()

        tcpServer
            .webSocket("/ws", object : WebSocketListener<Any> {

                override fun onOpenMessage(
                    channel: Channel,
                    headers: HttpHeaders,
                    params: Map<String, List<String>>
                ) {
                    val insocket = channel.remoteAddress() as InetSocketAddress
                    val clientIP = insocket.address.hostAddress
                    LogManager.d("SocketService", "connect client: $clientIP")
                    LogManager.d("SocketService", "connect params: ${GsonUtils.toJson(params)}")
                    if (params.isEmpty()) {
                        LogManager.d("SocketService", "connect params is empty: $clientIP")
                    }
//                    if (!headers.contains("auth")) {
//                        LogManager.d("SocketService", "connect is not ok, then closed")
//                        channel.writeAndFlush("is not ok")
//                        channel.close()
//                    }
                }

                override fun onTextMessage(textMsg: String, channel: Channel) {
                    LogManager.d("SocketService", "onTextMessage : $textMsg")
                }

                override fun onBinaryMessage(binaryMsg: ByteBuf, channel: Channel) {
                    LogManager.d(
                        "SocketService",
                        "onBinaryMessage : ${GsonUtils.toJson(binaryMsg)}"
                    )
                }

                override fun onPingMessage(frame: PingWebSocketFrame, channel: Channel) {
                    super.onPingMessage(frame, channel)
                }

                override fun onCloseMessage(channel: Channel) {
                    val ip = channel.remoteAddress().toString()
                    LogManager.d("SocketService", "disconnect client: $ip")
                }
            })
            .start()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {

        tcpServer.close()
        super.onDestroy()
    }


    override fun onBind(intent: Intent): IBinder? {
        return null
    }
}


fun main() {
    val serverBuilder = ServerBuilder {
        port { 9999 }
        serverType { ServerType.UDP }
        converter {
            GsonConverter()
        }
        logProxy {
            LogProxyImpl
        }
    }.build()
    serverBuilder.start()
}